/*
 * J24Frame.java
 *
 * Created on 19. September 2008, 15:56
 */

package j24;

import java.io.FileWriter;
import java.io.IOException;
import javax.swing.SpinnerNumberModel;
import net.sourceforge.jeval.EvaluationException;
import net.sourceforge.jeval.Evaluator;

/**
 *
 * @author  uli
 */
public class J24Frame extends javax.swing.JFrame {
    
    
    //Constants determinating the calculated range
    int upperLimit = 9;
    int lowerLimit = 1;
    int numCount = 4; //Do NOT change before implemented extended bracket algorithm
    int desiredResult = 24;
    
    //Switches
    boolean enableOneModulus = false;
    boolean enableTwoModuli = false;
    boolean strictModulus = true; //Filter modulus results where the modulus is greater than the main number
    boolean enableStd = true;

    static final char[] ops = {'+','-','*','/'}; //All operators available

    //Expression string builder
    StringBuilder expBuilder = new StringBuilder();
    //Evaluator
    Evaluator ev = new Evaluator();
    //Numbers iterated through
    int[] nums = new int[numCount];
    //Operators iterated through
    int[] opIds = new int[numCount - 1]; //Saves the ops indices of the operators currently used in the loop
    
    double res;

    /** Creates new form J24Frame */
    public J24Frame() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        upperLimitLabel = new javax.swing.JLabel();
        upperLimitSpinner = new javax.swing.JSpinner();
        lowerLimitLabel = new javax.swing.JLabel();
        lowerLimitSpinner = new javax.swing.JSpinner();
        targetLabel = new javax.swing.JLabel();
        targetSpinner = new javax.swing.JSpinner();
        fileLabel = new javax.swing.JLabel();
        fileField = new javax.swing.JTextField();
        okButton = new javax.swing.JButton();
        enableStdCheckbox = new javax.swing.JCheckBox();
        enable1ModulusCheckbox = new javax.swing.JCheckBox();
        enable2ModulusCheckbox = new javax.swing.JCheckBox();
        strictModulusCheckbox = new javax.swing.JCheckBox();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("J24");

        upperLimitLabel.setText("Upper limit:");

        upperLimitSpinner.setModel(new SpinnerNumberModel(9, 1, 9999, 1));
        upperLimitSpinner.setValue(9);

        lowerLimitLabel.setText("Lower limit:");

        lowerLimitSpinner.setModel(new SpinnerNumberModel(0, 0, 9999, 1));

        targetLabel.setText("Target:");

        targetSpinner.setModel(new SpinnerNumberModel(24, 0, 999999, 1));

        fileLabel.setText("File:");

        fileField.setText("/dev/shm/24.txt");

        okButton.setText("OK");
        okButton.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                okButtonMouseClicked(evt);
            }
        });

        enableStdCheckbox.setSelected(true);
        enableStdCheckbox.setText("Enable standard algebra");

        enable1ModulusCheckbox.setText("Enable one-variable modulus");

        enable2ModulusCheckbox.setText("Enable two-variable modulus");

        strictModulusCheckbox.setSelected(true);
        strictModulusCheckbox.setText("Strict modulus");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(upperLimitLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(upperLimitSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 64, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(targetLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(targetSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(fileLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(lowerLimitLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(lowerLimitSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addGroup(layout.createSequentialGroup()
                                .addGap(12, 12, 12)
                                .addComponent(fileField))))
                    .addComponent(enable2ModulusCheckbox)
                    .addComponent(okButton, javax.swing.GroupLayout.DEFAULT_SIZE, 364, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(enableStdCheckbox)
                            .addComponent(enable1ModulusCheckbox))
                        .addGap(18, 18, 18)
                        .addComponent(strictModulusCheckbox)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(upperLimitLabel)
                    .addComponent(upperLimitSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lowerLimitLabel)
                    .addComponent(lowerLimitSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(targetLabel)
                    .addComponent(fileField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(fileLabel)
                    .addComponent(targetSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(enableStdCheckbox)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(enable1ModulusCheckbox)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(enable2ModulusCheckbox))
                    .addGroup(layout.createSequentialGroup()
                        .addGap(23, 23, 23)
                        .addComponent(strictModulusCheckbox)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(okButton)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

private void okButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_okButtonMouseClicked
            
            //Init file output
    
            //Switches
            enableOneModulus = enable1ModulusCheckbox.isSelected();
            enableTwoModuli = enable2ModulusCheckbox.isSelected();
            strictModulus = strictModulusCheckbox.isSelected(); //Filter modulus results where the modulus is greater than the main number
            enableStd = enableStdCheckbox.isSelected();
            FileWriter fw = null;
            try
            {
                for (int i = 0; i < nums.length - 1; i++)
                {
                    nums[i] = lowerLimit;
                    opIds[i] = 0;
                }
                
                nums[nums.length - 1] = 0;
                fw = new FileWriter(fileField.getText());
                
                //Init statistics variables
                int stdCorrectResults = 0;
                int stdAllResults = 0;
                
                int mod1CorrectResults = 0;
                int mod1AllResults = 0;
                
                int mod2CorrectResults = 0;
                int mod2AllResults = 0;

                //Operator loop
                for (int opI = 0; opI <= 4*opIds.length - 1; opI++)
                {
                    //Number loop
                    // <editor-fold>
                    for (int numPerms = 0; numPerms < (int) Math.pow(upperLimit - lowerLimit,numCount); numPerms++)
                    {
                        ///////////////
                        //Test the standard arithmetics
                        //////////////
                        //<editor-fold>
                        if(enableStd)
                        {
                        //(x x) (x x)
                        if(
                            !(opIds[0] == 0 && opIds[1] == 0 && opIds[2] == 0) // + + +
                            && !(opIds[0] == 2 && opIds[1] == 2 && opIds[2] == 2) // * * *
                            )
                        {
                            expBuilder = new StringBuilder();
                            expBuilder.append('(');
                            expBuilder.append(nums[0]);
                            expBuilder.append(ops[opIds[0]]);
                            expBuilder.append(nums[1]);
                            expBuilder.append(')');
                            expBuilder.append(ops[opIds[1]]);
                            expBuilder.append('(');
                            expBuilder.append(nums[2]);
                            expBuilder.append(ops[opIds[2]]);
                            expBuilder.append(nums[3]);
                            expBuilder.append(')');
                            res = ev.getNumberResult(expBuilder.toString());
                            if (res == desiredResult)
                            {
                                fw.write(expBuilder.toString() + "=" + (int)res + "\n");
                                stdCorrectResults++;
                            }
                            stdAllResults++;
                        }
                        //x ([x x] x)
                        if(
                                !(opIds[0] == 0 && opIds[1] == 0 && opIds[2] == 0) // + + +
                                && !(opIds[0] == 2 && opIds[1] == 2 && opIds[2] == 2) // * * *
                                )
                        {
                            expBuilder = new StringBuilder();
                            expBuilder.append(nums[0]);
                            expBuilder.append(ops[opIds[0]]);
                            expBuilder.append("((");
                            expBuilder.append(nums[1]);
                            expBuilder.append(ops[opIds[1]]);
                            expBuilder.append(nums[2]);
                            expBuilder.append(')');
                            expBuilder.append(ops[opIds[2]]);
                            expBuilder.append(nums[3]);
                            expBuilder.append(')');
                            res = ev.getNumberResult(expBuilder.toString());
                            if (res == desiredResult)
                            {
                                fw.write(expBuilder.toString() + "=" + (int)res + "\n");
                                stdCorrectResults++;
                            }
                            stdAllResults++;
                        }
                        //x (x [x x])
                        if(
                                !(opIds[0] == 0 && opIds[1] == 0 && opIds[2] == 0) // + + +
                                && !(opIds[0] == 2 && opIds[1] == 2 && opIds[2] == 2) // * * *
                                )
                        {
                            expBuilder = new StringBuilder();
                            expBuilder.append(nums[0]);
                            expBuilder.append(ops[opIds[0]]);
                            expBuilder.append('(');
                            expBuilder.append(nums[1]);
                            expBuilder.append(ops[opIds[1]]);
                            expBuilder.append("(");
                            expBuilder.append(nums[2]);
                            expBuilder.append(ops[opIds[2]]);
                            expBuilder.append(nums[3]);
                            expBuilder.append("))");
                            res = ev.getNumberResult(expBuilder.toString());
                            if (res == desiredResult)
                            {
                                fw.write(expBuilder.toString() + "=" + (int)res + "\n");
                                stdCorrectResults++;
                            }
                            stdAllResults++;
                        }
                        //([x x] x) x
                        if(
                                !(opIds[0] == 0 && opIds[1] == 0 && opIds[2] == 0) // + + +
                                && !(opIds[0] == 2 && opIds[1] == 2 && opIds[2] == 2) // * * *
                                )
                        {
                            expBuilder = new StringBuilder();   
                            expBuilder.append("((");
                            expBuilder.append(nums[0]);
                            expBuilder.append(ops[opIds[0]]);
                            expBuilder.append(nums[1]);
                            expBuilder.append(')');
                            expBuilder.append(ops[opIds[1]]);
                            expBuilder.append(nums[2]);
                            expBuilder.append(')');
                            expBuilder.append(ops[opIds[2]]);
                            expBuilder.append(nums[3]);
                            res = ev.getNumberResult(expBuilder.toString());
                            if (res == desiredResult)
                            {
                                fw.write(expBuilder.toString() + "=" + (int)res + "\n");
                                stdCorrectResults++;
                            }
                            stdAllResults++;
                        }
                        //(x [x x]) x
                        if(
                                !(opIds[0] == 0 && opIds[1] == 0 && opIds[2] == 0) // + + +
                                && !(opIds[0] == 2 && opIds[1] == 2 && opIds[2] == 2) // * * *
                                )
                        {
                            expBuilder = new StringBuilder();
                            expBuilder.append('(');
                            expBuilder.append(nums[0]);
                            expBuilder.append(ops[opIds[0]]);
                            expBuilder.append('(');
                            expBuilder.append(nums[1]);
                            expBuilder.append(ops[opIds[1]]);
                            expBuilder.append(nums[2]);
                            expBuilder.append("))");
                            expBuilder.append(ops[opIds[2]]);
                            expBuilder.append(nums[3]);
                            res = ev.getNumberResult(expBuilder.toString());
                            if (res == desiredResult)
                            {
                                fw.write(expBuilder.toString() + "=" + (int)res + "\n");
                                stdCorrectResults++;
                            }
                            stdAllResults++;
                        }
                        //x (x x x)
                        if(
                                !(opIds[0] == 0 && opIds[1] == 0 && opIds[2] == 0) // + + +
                                && !(opIds[0] == 2 && opIds[1] == 2 && opIds[2] == 2) // * * *
                                )
                        {
                            expBuilder = new StringBuilder();
                            expBuilder.append(nums[0]);
                            expBuilder.append(ops[opIds[0]]);
                            expBuilder.append('(');
                            expBuilder.append(nums[1]);
                            expBuilder.append(ops[opIds[1]]);
                            expBuilder.append(nums[2]);
                            expBuilder.append(ops[opIds[2]]);
                            expBuilder.append(nums[3]);
                            expBuilder.append(')');
                            res = ev.getNumberResult(expBuilder.toString());
                            if (res == desiredResult)
                            {
                                fw.write(expBuilder.toString() + "=" + (int)res + "\n");
                                stdCorrectResults++;
                            }
                            stdAllResults++;
                        }
                        //(x x x) x
                        if(
                                !(opIds[0] == 0 && opIds[1] == 0 && opIds[2] == 0) // + + +
                                && !(opIds[0] == 2 && opIds[1] == 2 && opIds[2] == 2) // * * *
                                )
                        {
                            expBuilder = new StringBuilder();
                            expBuilder.append('(');
                            expBuilder.append(nums[0]);
                            expBuilder.append(ops[opIds[0]]);
                            expBuilder.append(nums[1]);
                            expBuilder.append(ops[opIds[1]]);
                            expBuilder.append(nums[2]);
                            expBuilder.append(')');
                            expBuilder.append(ops[opIds[2]]);
                            expBuilder.append(nums[3]);
                            res = ev.getNumberResult(expBuilder.toString());
                            if (res == desiredResult)
                            {
                                fw.write(expBuilder.toString() + "=" + (int)res + "\n");
                                stdCorrectResults++;
                            }
                            stdAllResults++;
                        }
                        //x x (x x)
                        if(
                                !(opIds[0] == 0 && opIds[1] == 0 && opIds[2] == 0) // + + +
                                && !(opIds[0] == 2 && opIds[1] == 2 && opIds[2] == 2) // * * *
                                )
                        {
                            expBuilder = new StringBuilder();
                            expBuilder.append(nums[0]);
                            expBuilder.append(ops[opIds[0]]);
                            expBuilder.append(nums[1]);
                            expBuilder.append(ops[opIds[1]]);
                            expBuilder.append('(');
                            expBuilder.append(nums[2]);
                            expBuilder.append(ops[opIds[2]]);
                            expBuilder.append(nums[3]);
                            expBuilder.append(')');
                            res = ev.getNumberResult(expBuilder.toString());
                            if (res == desiredResult)
                            {
                                fw.write(expBuilder.toString() + "=" + (int)res + "\n");
                                stdCorrectResults++;
                            }
                            stdAllResults++;
                        }
                        //x (x x) x
                        if(
                                !(opIds[0] == 0 && opIds[1] == 0 && opIds[2] == 0) // + + +
                                && !(opIds[0] == 2 && opIds[1] == 2 && opIds[2] == 2) // * * *
                                )
                        {
                            expBuilder = new StringBuilder();
                            expBuilder.append(nums[0]);
                            expBuilder.append(ops[opIds[0]]);
                            expBuilder.append('(');
                            expBuilder.append(nums[1]);
                            expBuilder.append(ops[opIds[1]]);
                            expBuilder.append(nums[2]);
                            expBuilder.append(')');
                            expBuilder.append(ops[opIds[2]]);
                            expBuilder.append(nums[3]);
                            res = ev.getNumberResult(expBuilder.toString());
                            if (res == desiredResult)
                            {
                                fw.write(expBuilder.toString() + "=" + (int)res + "\n");
                                stdCorrectResults++;
                            }
                            stdAllResults++;
                        }
                        //(x x) x x
                        if(
                                !(opIds[0] == 0 && opIds[1] == 0 && opIds[2] == 0) // + + +
                                && !(opIds[0] == 2 && opIds[1] == 2 && opIds[2] == 2) // * * *
                                )
                        {
                            expBuilder = new StringBuilder();
                            expBuilder.append('(');
                            expBuilder.append(nums[0]);
                            expBuilder.append(ops[opIds[0]]);
                            expBuilder.append(nums[1]);
                            expBuilder.append(')');
                            expBuilder.append(ops[opIds[1]]);
                            expBuilder.append(nums[2]);
                            expBuilder.append(ops[opIds[2]]);
                            expBuilder.append(nums[3]);
                            res = ev.getNumberResult(expBuilder.toString());
                            if (res == desiredResult)
                            {
                                fw.write(expBuilder.toString() + "=" + (int)res + "\n");
                                stdCorrectResults++;
                            }
                            stdAllResults++;
                        }
                        //x x x x
                        expBuilder = new StringBuilder();
                        expBuilder.append(nums[0]);
                        expBuilder.append(ops[opIds[0]]);
                        expBuilder.append(nums[1]);
                        expBuilder.append(ops[opIds[1]]);
                        expBuilder.append(nums[2]);
                        expBuilder.append(ops[opIds[2]]);
                        expBuilder.append(nums[3]);
                        res = ev.getNumberResult(expBuilder.toString());
                        if (res == desiredResult)
                        {
                            fw.write(expBuilder.toString() + "=" + (int)res + "\n");
                            stdCorrectResults++;
                        }
                        stdAllResults++;
                        //</editor-fold>
                        }

                    
                        //////////////
                        //Test modular algebras with one modulus variable
                        //////////////
                        //<editor-fold>
                        if(enableOneModulus)//&& opI % 4 == 0)
                        {
                            int res;
                            for(int i = 0; i < numCount;i++) //All numbers are tested as modulus
                            {
                                //x x x
                                expBuilder = new StringBuilder();
                                expBuilder.append(nums[(i+1)%numCount]);
                                expBuilder.append(ops[opIds[0]]);
                                expBuilder.append(nums[(i+2)%numCount]);
                                expBuilder.append(ops[opIds[1]]);
                                expBuilder.append(nums[(i+3)%numCount]);
                                res = (int) ev.getNumberResult(expBuilder.toString()) % nums[i];
                                if(res == desiredResult)
                                {
                                    fw.write(expBuilder.toString() + "=" + res + "\n");
                                    mod1CorrectResults++;
                                }
                                mod1AllResults++;
                                //(x x) x
                                if(opIds[1] != 0 && opIds[1] != 2) //Dont calculate if the brace term is added or multiplied
                                {
                                    expBuilder = new StringBuilder();
                                    expBuilder.append('(');
                                    expBuilder.append(nums[(i+1)%numCount]);
                                    expBuilder.append(ops[opIds[0]]);
                                    expBuilder.append(nums[(i+2)%numCount]);
                                    expBuilder.append(')');                                    
                                    expBuilder.append(ops[opIds[1]]);
                                    expBuilder.append(nums[(i+3)%numCount]);
                                    res = (int) ev.getNumberResult(expBuilder.toString()) % nums[i];
                                    if(res == desiredResult)
                                    {
                                        fw.write(expBuilder.toString() + "=" + res + "\n");
                                        mod1CorrectResults++;
                                    }
                                    mod1AllResults++;                                    
                                }
                                //x (x x)
                                if(opIds[0] != 0 && opIds[0] != 2) //Dont calculate if the brace term is added or multiplied
                                {
                                    expBuilder = new StringBuilder();
                                    expBuilder.append(nums[(i+1)%numCount]);
                                    expBuilder.append(ops[opIds[0]]);
                                    expBuilder.append('(');
                                    expBuilder.append(nums[(i+2)%numCount]);                                    
                                    expBuilder.append(ops[opIds[1]]);
                                    expBuilder.append(nums[(i+3)%numCount]);
                                    expBuilder.append(')');
                                    res = (int) ev.getNumberResult(expBuilder.toString()) % nums[i];
                                    if(res == desiredResult)
                                    {
                                        fw.write(expBuilder.toString() + "\u2263" + res +  " (mod " + nums[3] + ")\n");
                                        mod1CorrectResults++;
                                    }
                                    mod1AllResults++;                                    
                                }
                            }
                        }
                        //</editor-fold>
                        
                        //////////////
                        //Test modular algebras with two modulus variables
                        //////////////
                        //<editor-fold>
                        if(enableTwoModuli)
                        {
                            int resInt;
                            double modDouble;
                            int modulus;
                            StringBuilder modExpBuilder;
                            for(int i = 0; i < numCount;i++) //All numbers are tested as modulus
                            {                                
                                expBuilder = new StringBuilder();
                                expBuilder.append(nums[i]);
                                expBuilder.append(ops[opIds[0]]);
                                expBuilder.append(nums[(i+1)%numCount]);
                                resInt = (int) ev.getNumberResult(expBuilder.toString());
                                //Continue if the left side result is 0
                                if(resInt == 0) {continue;}
                                
                                modExpBuilder = new StringBuilder();
                                modExpBuilder.append(nums[(i+2)%numCount]);
                                modExpBuilder.append(ops[opIds[1]]);
                                modExpBuilder.append(nums[(i+3)%numCount]);
                                modDouble = ev.getNumberResult(modExpBuilder.toString());
                                if(Double.isInfinite(modDouble)) {continue;} //x/0 --> Inf.
                                    
                                modulus = (int) modDouble;
                                
                                //Filter invalid results
                                if(strictModulus && modulus > resInt) {continue;}
                                //Continue if the modulus is 0
                                if(modDouble == 0) {continue;}
                                //Calculate final result : res % modulus
                                resInt %= modulus;
                                
                                if(resInt == desiredResult)
                                {
                                    fw.write(expBuilder.toString() + "\u2263" + resInt + " (mod " + modExpBuilder.toString() + ")\n");
                                    mod2CorrectResults++;
                                }
                                mod2AllResults++;
                            }
                        } //Number loop
                        //</editor-fold>
                        
                        ////End tests
                    
                        //Increment first number with overflow handling
                        for (int i = 0; i < numCount; i++)
                        {
                            nums[i] = ((nums[i] + 1) % upperLimit) + lowerLimit;
                            if (nums[i] != lowerLimit)
                            {
                                break;
                            }
                        }
                    }
                    // </editor-fold>
                    
                    //Increment last operator index with overflow handling
                    for (int i = 0; i < numCount - 2; i++)
                    {
                        opIds[i] = (opIds[i] + 1) % 4;
                        if (opIds[i] != 0)
                        {
                            break;
                        }
                    }
                }
                
                //Print out statistics
                System.out.println("Statistics:");
                System.out.println("  Standard arithmetics:");
                System.out.println("    Number of results:" + stdAllResults);
                System.out.println("    Correct results:" + stdCorrectResults);
                System.out.println("    Wrong results:" + (stdAllResults-stdCorrectResults) );
                System.out.println("  One Modulus:");
                System.out.println("    Number of results:" + mod1AllResults);
                System.out.println("    Correct results:" + mod1CorrectResults);
                System.out.println("    Wrong results:" + (mod1AllResults-mod1CorrectResults) );
                System.out.println("  Two Moduli:");
                System.out.println("    Number of results:" + mod2AllResults);
                System.out.println("    Correct results:" + mod2CorrectResults);
                System.out.println("    Wrong results:" + (mod2AllResults-mod2CorrectResults) );
                //Close the file writer
                fw.close();
            }
            catch (IOException ex)
            {
                ex.printStackTrace();
            }
            catch (EvaluationException ex)
            {
                ex.printStackTrace();
            }
            finally
            {
                try
                {
                    fw.close();
                }
                catch (IOException ex)
                {
                    ex.printStackTrace();
                }
            }
}//GEN-LAST:event_okButtonMouseClicked

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new J24Frame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox enable1ModulusCheckbox;
    private javax.swing.JCheckBox enable2ModulusCheckbox;
    private javax.swing.JCheckBox enableStdCheckbox;
    private javax.swing.JTextField fileField;
    private javax.swing.JLabel fileLabel;
    private javax.swing.JLabel lowerLimitLabel;
    private javax.swing.JSpinner lowerLimitSpinner;
    private javax.swing.JButton okButton;
    private javax.swing.JCheckBox strictModulusCheckbox;
    private javax.swing.JLabel targetLabel;
    private javax.swing.JSpinner targetSpinner;
    private javax.swing.JLabel upperLimitLabel;
    private javax.swing.JSpinner upperLimitSpinner;
    // End of variables declaration//GEN-END:variables

}
